142. Linked List Cycle II

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

Note: Do not modify the linked list.

Example 1:

1
2
3
Input: head = [3,2,0,-4], pos = 1
Output: tail connects to node index 1
Explanation: There is a cycle in the linked list, where tail connects to the second node.

img

Example 2:

1
2
3
Input: head = [1,2], pos = 0
Output: tail connects to node index 0
Explanation: There is a cycle in the linked list, where tail connects to the first node.

img

Example 3:

1
2
3
Input: head = [1], pos = -1
Output: no cycle
Explanation: There is no cycle in the linked list.

img

解法1

双指针,快指针在前,慢指针在后.快指针一次走两步,慢指针一次走一步.如果链表无环,快指针一定先达到链表尾.否则,快指针比满指针走的快,快指针和慢指针一定会在链表上相遇.

找到快慢指针相遇的环中节点后,接下来要怎么找入环节点呢.我们知道快指针比慢指针快,如果要是能让快指针和慢指针在入环节点处相遇,那么需要快指针比慢指针多走一个环的长度的距离.当快指针和慢指针都在环上走时, 如果让慢指针先出发,当快指针赶上慢指针时,快指针正好比慢指针多走了一个环长的距离.所以,只需要让慢指针先走一个环的长度的距离,然后快指针和慢指针一起走,快指针来追赶慢指针,当慢指针赶上快指针时,正好是在入环节点上.

那么如何求环的长度呢?只需要一个指针从(快慢指针在环上相遇的节点)相遇节点出发, 再次回到该节点所需要走的步数就是环的长度.

为什么必须快指针在前,慢指针在呢?举个例子

如果链表是1->2->3.
如果初始化时,慢指针在前,指向节点2, 快指针在后,指向1,那么快指针会赶上慢指针,即快慢指针会在节点3相遇,那么结束条件就不能是快指针和慢指针是否相遇.如果如上所示,即使没环,快慢指针也会在节点3处相遇.